package com.excilys.formation.project.entities;

import java.io.Serializable;
import java.util.Set;

import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;

import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotEmpty;

/**
 * Client est la classe de lien avec la table client en base pour l'ORM.
 * 
 * @author excilys
 */
@Entity
@Table(uniqueConstraints = { @UniqueConstraint(columnNames = { "login" }) })
@SuppressWarnings("serial")
public class Client implements Serializable {
    /**
     * Clef primaire du client.
     */
    private long id;
    /**
     * Nom du client.
     */
    private String nom;
    /**
     * Prénom du client.
     */
    private String prenom;
    /**
     * Identifiant (unique) du client pour se connecter sur le site.
     */
    private String login;
    /**
     * Mot de passe du client pour se connecter sur le site. Doit être encrypté en SHA-256.
     */
    private String password;

    /**
     * Comptes possédés par le client.
     */
    private Set<Compte> comptes;

    /**
     * Taille minimale de l'identifiant de connection.
     */
    public static final int LOGIN_MIN_SIZE = 6;
    /**
     * Taille maximale de l'identifiant de connection.
     */
    public static final int LOGIN_MAX_SIZE = 20;
    /**
     * Taille du mot de passe de connection (SHA-256).
     */
    private static final int PASSWORD_SIZE = 64;

    /**
     * Renvoie la clef primaire Change la clef primaire (auto générée).
     * 
     * @return id
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public long getId() {
        return id;
    }

    /**
     * Change la clef primaire (auto générée).
     * 
     * @param id
     *            Clef primaire du client.
     */
    public void setId(final long id) {
        this.id = id;
    }

    /**
     * Renvoie le nom du client.
     * 
     * @return nom
     */
    @NotEmpty
    public String getNom() {
        return nom;
    }

    /**
     * Change le nom du client.
     * 
     * @param nom
     *            Nom du client.
     */
    public void setNom(final String nom) {
        this.nom = nom;
    }

    /**
     * Renvoie le prénom du client.
     * 
     * @return prenom
     */
    @NotEmpty
    public String getPrenom() {
        return prenom;
    }

    /**
     * Change le prénom du client.
     * 
     * @param prenom
     *            Prénom du client.
     */
    public void setPrenom(final String prenom) {
        this.prenom = prenom;
    }

    /**
     * Renvoie l'identifiant de connection du client (entre 6 et 20 charactères). Unique
     * 
     * @return login
     */
    @NotEmpty
    @Length(min = LOGIN_MIN_SIZE, max = LOGIN_MAX_SIZE)
    public String getLogin() {
        return login;
    }

    /**
     * Change l'identifiant de connection du client (entre 6 et 20 charactères).
     * 
     * @param login
     *            Identifiant du client pour se connecter sur le site.
     */
    public void setLogin(final String login) {
        this.login = login;
    }

    /**
     * Renvoie le mot de passe de connection du client (minimum 6 charactères).
     * 
     * @return password
     */
    @NotEmpty
    @Length(min = PASSWORD_SIZE, max = PASSWORD_SIZE)
    public String getPassword() {
        return password;
    }

    /**
     * Change le mot de passe de connection du client (minimum 6 charactères).
     * 
     * @param password
     *            Mot de passe du client pour se connecter sur le site.
     */
    public void setPassword(final String password) {
        this.password = password;
    }

    /**
     * Renvoie l'ensemble des comptes possédés par le client.
     * 
     * @return comptes
     */
    @OneToMany(mappedBy = "client", fetch = FetchType.LAZY)
    public Set<Compte> getComptes() {

        return comptes;
    }

    /**
     * Change l'ensemble des comptes possédés par le client.
     * 
     * @param comptes
     *            Le nouvel ensemble de comptes.
     */
    public void setComptes(final Set<Compte> comptes) {
        this.comptes = comptes;
    }

}
